package com.blacksheep.mtm.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.blacksheep.mtm.common.exception.XmallException;
import com.blacksheep.mtm.common.utils.AliyunSMS;
import com.blacksheep.mtm.common.utils.FileUtil;
import com.blacksheep.mtm.common.utils.IDUtil;
import com.blacksheep.mtm.dao.*;
import com.blacksheep.mtm.dto.MedicineItemDto;
import com.blacksheep.mtm.dto.OrderDto;
import com.blacksheep.mtm.dto.OrderDtoSimple;
import com.blacksheep.mtm.dto.OrderExcelDto;
import com.blacksheep.mtm.dto.front.OrderFrontDto;
import com.blacksheep.mtm.dto.front.OrderUpdateVo;
import com.blacksheep.mtm.pojo.common.DataTablesResult;
import com.blacksheep.mtm.pojo.manager.*;
import com.blacksheep.mtm.service.OrderService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private TbOrderMapper orderMapper;
    @Autowired
    private TbOrderShippingMapper orderShippingMapper;
    @Autowired
    private TbOrderItemMapper orderItemMapper;
    @Autowired
    private TbUserMapper userMapper;
    @Autowired
    private TbMemberMapper memberMapper;
    @Autowired
    private TbMedicineMapper medicineMapper;

    @Autowired
    private TbOrderReviewMapper orderReviewMapper;

    @Autowired
    private TbWxOrderMapper wxOrderMapper;

    @Autowired
    private TbOrderCancelMapper cancelMapper;
    final static Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);


    @Override
    public DataTablesResult getOrderList(int draw, int start, int length, int[] state, String search, String minDate, String maxDate, String orderCol, String orderDir) {
        DataTablesResult result = new DataTablesResult();
        List<OrderFrontDto> dtoList = new ArrayList<>();
        //分页
        PageHelper.startPage(start / length + 1, length);
        List<OrderFrontDto> list = orderMapper.selectList("%" + search + "%", state, minDate, maxDate, orderCol, orderDir);
        PageInfo<OrderFrontDto> pageInfo = new PageInfo<>(list);
        for (OrderFrontDto dto : list) {
            //获得客服name
            if (dto.getCcId() != null) {
                String name = userMapper.getUsernamebyId(dto.getCcId());
                dto.setCcName(name);
            }
            //配药人name
            if (dto.getDispenserId() != null) {
                String name = userMapper.getUsernamebyId(dto.getDispenserId());
                dto.setDispenserName(name);
            }
            //调度人name
            if (dto.getDispatcherId() != null) {
                String name = userMapper.getUsernamebyId(dto.getDispatcherId());
                dto.setDispatcherName(name);
            }
            dtoList.add(dto);
        }
        result.setRecordsFiltered((int) pageInfo.getTotal());
        result.setDraw(draw);
        result.setData(dtoList);
        return result;
    }



    @Override
    public DataTablesResult getUncomfiredOrderList(int draw, int start, int length, int[] state,int isPrint, String search, String minDate, String maxDate, String orderCol, String orderDir) {
        DataTablesResult result = new DataTablesResult();
        //分页
        PageHelper.startPage(start / length + 1, length);
        List<OrderFrontDto> list = orderMapper.selectListDto("%" + search + "%", state, isPrint,minDate, maxDate, orderCol, orderDir);
        PageInfo<OrderFrontDto> pageInfo = new PageInfo<>(list);
        for (OrderFrontDto dto : list) {
            TbMember member = memberMapper.selectByPrimaryKey(dto.getMemberId());
            if (member != null) {
                // 真实姓名为空就填入用户名
                String name = StringUtils.isBlank(member.getRealname())? member.getUsername():member.getRealname();
                dto.setMemberName(name);
            }
            // 获取药品清单
            TbOrderItemExample example = new TbOrderItemExample();
            example.createCriteria().andOrderIdEqualTo(dto.getOrderId());
            List<MedicineItemDto> medicineItemDtos = orderItemMapper.selectMedicinListByOrder(dto.getOrderId());
            dto.setMedicineList(medicineItemDtos);
        }
        result.setRecordsFiltered((int) pageInfo.getTotal());
        result.setDraw(draw);
        result.setData(list);
        return result;
    }

    @Override
    public DataTablesResult getCancelOrderList(int draw, int start, int length, int[] state,int isPrint, String search, String minDate, String maxDate, String orderCol, String orderDir) {
        DataTablesResult result = new DataTablesResult();
        //分页
        PageHelper.startPage(start / length + 1, length);
        List<OrderFrontDto> list = orderMapper.selectCancelListDto("%" + search + "%",minDate, maxDate, orderCol, orderDir);
        PageInfo<OrderFrontDto> pageInfo = new PageInfo<>(list);
        for (OrderFrontDto dto : list) {
            TbMember member = memberMapper.selectByPrimaryKey(dto.getMemberId());
            if (member != null) {
                // 真实姓名为空就填入用户名
                String name = StringUtils.isBlank(member.getRealname())? member.getUsername():member.getRealname();
                dto.setMemberName(name);
            }
            // 获取药品清单
            TbOrderItemExample example = new TbOrderItemExample();
            example.createCriteria().andOrderIdEqualTo(dto.getOrderId());
            List<MedicineItemDto> medicineItemDtos = orderItemMapper.selectMedicinListByOrder(dto.getOrderId());
            dto.setMedicineList(medicineItemDtos);
        }
        result.setRecordsFiltered((int) pageInfo.getTotal());
        result.setDraw(draw);
        result.setData(list);
        return result;
    }

    @Override
    @Transactional
    public int updateOrder(String id, OrderUpdateVo vo) {
        TbOrder o  = orderMapper.selectByPrimaryKey(id);
        if (o ==null){
            throw new XmallException("更新失败，订单不存在");
        }
        TbOrder order = new TbOrder();
        order.setOrderId(id);
        order.setInsurance(vo.getInsurance());
        order.setInsuranceType(vo.getInsuranceType());
        order.setPaymentType(vo.getPaymentType());
        order.setReserveTime(vo.getReserveTime());
        order.setPrescriptionPic(vo.getPrescriptionPic());
        TbOrderShipping shipping = new TbOrderShipping();
        shipping.setShippingId(o.getShippingId());
        shipping.setAddressType(vo.getAddressType());
        shipping.setReceiverName(vo.getReceiverName());
        shipping.setReceiverPhone(vo.getReceiverPhone());
        shipping.setReceiverState(vo.getReceiverState());
        shipping.setReceiverCity(vo.getReceiverCity());
        shipping.setReceiverDistrict(vo.getReceiverDistrict());
        shipping.setReceiverAddress(vo.getReceiverAddress());
        int orderResult = orderMapper.updateByPrimaryKeySelective(order);
        if (orderResult < 1){
            throw new XmallException("更新订单失败");
        }
        int shippingResult = orderShippingMapper.updateByPrimaryKeySelective(shipping);
        if (shippingResult < 1){
            throw new XmallException("更新运单失败");
        }

        List<MedicineItemDto> list = vo.getMedicineList();
        if (list !=null && list.size()>0){
            for (MedicineItemDto medicine:list){
                TbOrderItem item = orderItemMapper.selectByMedicineAndOrder(id,medicine.getItemId());
                item.setNum(medicine.getNum());
                if (orderItemMapper.updateByPrimaryKeySelective(item)<1){
                    throw new XmallException("更新订单失败");
                }
            }
        }
        return 0;
    }

    @Override
    @Transactional
    public int cancelOrder(String orderId,String content) {
                String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long memberId = userMapper.getUserIdByUsername(username); //下单人
        int result = orderMapper.cancelOrderByPrimaryKey(orderId);
        if (result < 1) {
            throw new XmallException("取消订单失败,请重新尝试");
        }

        TbOrderCancel cancel = new TbOrderCancel();
        cancel.setCancelContent(content);
        cancel.setOrderId(orderId);
        cancel.setUid(UUID.randomUUID().toString());
        cancel.setCreateby(memberId);
        cancel.setCreateTime(new Date());
        if (cancelMapper.insertSelective(cancel) < 1) {
            throw new XmallException("取消订单失败,请重新尝试");
        }
        return 0;
    }

    @Override
    @Transactional
    public TbOrder insertOrder(OrderDto orderDto,Integer wxOrderId) {
//        String username = SecurityUtils.getSubject().getPrincipal().toString();
//        Long memberId = userMapper.getUserIdByUsername(username); //下单人

//        TbMember member = memberMapper.selectMemberByOpenid(openId);
//        if (member == null) {
//            throw new XmallException("新增订单失败,请先登录或者绑定手机");
//        }

        TbMedicine medicine = medicineMapper.selectByPrimaryKey(Integer.parseInt(orderDto.getMedicineId()));
        if (medicine ==null){
            throw new XmallException("新增订单失败,药品错误");
        }
        TbOrderShipping orderShipping = new TbOrderShipping();

        TbOrderItem orderItem = new TbOrderItem();

        // 运单详情
        orderShipping.setAddressType(orderDto.getAddressType());
        orderShipping.setReceiverAddress(orderDto.getReceiverAddress());
        orderShipping.setReceiverCity(orderDto.getReceiverCity());
        orderShipping.setReceiverState(orderDto.getReceiverState());
        orderShipping.setReceiverDistrict(orderDto.getReceiverDistrict());
        orderShipping.setReceiverName(orderDto.getReceiverName());
        orderShipping.setReceiverPhone(orderDto.getReceiverPhone());





        

        orderItem.setNum(orderDto.getNum());
        orderItem.setItemId(orderDto.getMedicineId());
        orderItem.setManufacturer(medicine.getManufacturer());
        orderItem.setMedicineName(medicine.getMedicineName()+"("+medicine.getName()+")");
        orderItem.setSize(medicine.getStandard());
//                orderItem.setItemId(item.getItemId().toString());
        orderItem.setPrice(BigDecimal.valueOf(medicine.getPrice()));
        orderItem.setTotalFee(BigDecimal.valueOf(orderDto.getNum() * medicine.getPrice()));
//        orderItem.setExp(item.getExp());
//        orderItem.setBatchNumber(item.getBatchNumber());

        if (StringUtils.isBlank(orderItem.getItemId())) {
            throw new XmallException("新增订单失败,没有添加药品");
        }else {
//            TbMedicine medicine = medicineMapper.selectByPrimaryKey(Integer.parseInt(orderItem.getItemId()));
//            Date rtime = orderDto.getReserveTime();
//            if (rtime.getTime() < (new Date().getTime() + medicine.getBasicTime() * 60 * 60 * 1000)) {
//                throw new XmallException("药品基础时长为" + medicine.getBasicTime() + "小时");
//            }
        }

        TbOrder order = new TbOrder();
        String orderId = Long.toString(IDUtil.getRandomId());//生成订单id
        order.setReserveTime(orderDto.getReserveTime());
        order.setPaymentType(orderDto.getPaymentType());
        order.setStatus(0); //状态 0:订单默认状态,10:订单已确认,20:订单已配药,30:订单已分配派送员,40:订单已完成
        order.setOrderId(orderId);
        order.setMemberId(orderDto.getMemberId());
        order.setInsurance(orderDto.getInsurance());
        order.setInsuranceType(orderDto.getInsuranceType());
        order.setFreezing(orderDto.getFreezing());
        orderShipping.setOrderId(orderId);
        orderShipping.setShippingId(IDUtil.getRandomIdStr());
        orderItem.setOrderId(orderId);
        orderItem.setId(IDUtil.getRandomIdStr2());
        if (wxOrderId !=null){
            if (wxOrderMapper.updateStateByPrimaryKey(wxOrderId,1)<1){
                throw new XmallException("新增订单失败");
            }
            order.setStatus(10); //状态 0:订单默认状态,10:订单已确认,20:订单已配药,30:订单已分配派送员,40:订单已完成
        }
        //新增运输单
        int shippingResult = orderShippingMapper.insertSelective(orderShipping);
        if (shippingResult < 1) {
            throw new XmallException("新增订单失败,新建运单失败");
        }

        int orderListResult = orderItemMapper.insertSelective(orderItem);
        if (orderListResult < 1) {
            throw new XmallException("新增订单失败,插入订单详情失败");
        }

        order.setShippingId(orderShipping.getShippingId());
        order.setPrescriptionPic(orderDto.getPrescriptionPic());
        int result = orderMapper.insertSelective(order);
        if (result < 1) {
            throw new XmallException("新增订单失败");
        }
        return order;
    }



    @Override
    public int updateOrderCc(String[] id) {
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long ccId = userMapper.getUserIdByUsername(username);
        int result = orderMapper.updateCCidByPrimaryKey(id, ccId);
        if (result < 1) {
            throw new XmallException("更新联系人失败,请重新尝试");
        }
        return 0;
    }

    @Override
    @Transactional
    public int updateOrderDispatcher(String[] ids, Long mid) {
        for (String id : ids) {
            TbOrder order = orderMapper.selectByPrimaryKey(id);
            if (order != null) {
                String shippingId = order.getShippingId();
                if (StringUtils.isBlank(shippingId)) {
                    throw new XmallException("更新配送员失败,找不到运单号,该订单还没有创建运单");
                }
                TbOrderShipping shipping = orderShippingMapper.selectByPrimaryKey(shippingId);
                if (shipping == null) {
                    throw new XmallException("更新配送员失败,运单为空,该订单还没有创建运单");
                }
                TbMember deli = memberMapper.selectByPrimaryKey(mid);
                if (deli ==null){
                    throw new XmallException("更新配送员失败,配送员不存在");
                }
                if (deli.getState() <=0){
                    throw new XmallException("更新配送员失败,配送员已停用");
                }
                // 更新配送员
                int shipResult = orderShippingMapper.updateDeliveryidByPrimaryKey(mid, shippingId);
                if (shipResult < 1) {
                    throw new XmallException("更新配送员失败,无法添加配送员");
                }
                String SMSCode = "SMS_154591673";
                JSONObject jsonObject = new JSONObject();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分");
                jsonObject.put("name", deli.getRealname());
                jsonObject.put("time", sdf.format(order.getReserveTime()));
                jsonObject.put("order", id);
                try {
                    SendSmsResponse response =   AliyunSMS.sendSms(deli.getPhone(), SMSCode, jsonObject);
                    log.info("Code=" + response.getCode());
                    log.info("Message=" + response.getMessage());
                    log.info("RequestId=" + response.getRequestId());
                    log.info("BizId=" + response.getBizId());
                } catch (ClientException e) {
                    throw new XmallException(e.getErrMsg());
                }
            } else {
                throw new XmallException("更新配送员失败,订单不存在");
            }
        }
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long userId = userMapper.getUserIdByUsername(username);
        int result = orderMapper.updateDispatcherIdByPrimaryKey(ids, userId);
        if (result < 1) {
            throw new XmallException("更新配送员失败,请重新尝试");
        }

        return 0;
    }

    @Override
    public int updateOrderDispenser(String[] id) {
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long userId = userMapper.getUserIdByUsername(username);
        int result = orderMapper.updateDispenserIdByPrimaryKey(id, userId);
        if (result < 1) {
            throw new XmallException("更新发药员失败,请重新尝试");
        }

        return 0;
    }

    @Override
    public int updateOrderReserveTime(String id, String reserveTime) {
        TbOrder order = orderMapper.selectByPrimaryKey(id);
        if (order != null) {
            String shippingId = order.getShippingId();
            if (StringUtils.isBlank(shippingId)) {
                throw new XmallException("更新订单失败,找不到运单号,该订单还没有创建运单");
            }
            TbOrderShipping shipping = orderShippingMapper.selectByPrimaryKey(shippingId);
            if (shipping == null) {
                throw new XmallException("更新订单预约时间失败,运单为空,该订单还没有创建运单");
            }
            Date time = new Date();
            time.setTime(Long.parseLong(reserveTime));
            int result = orderMapper.updateReserveTimeByPrimaryKey(id, time);
            if (result < 1) {
                throw new XmallException("更新订单失败,请重新尝试");
            }
        } else {
            throw new XmallException("更新发药员失败,订单不存在");
        }
        return 0;
    }

    @Override
    @Transactional
    public int reviewOrder(String id,int state,String comment) {
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        Long userId = userMapper.getUserIdByUsername(username);

        TbOrderReview orderReview = new TbOrderReview();
        orderReview.setOperator(userId);
        orderReview.setComment(comment);
        orderReview.setUuid(UUID.randomUUID().toString());
        orderReview.setOrderId(id);
        int result = 0;
        if (state <=0){
            orderReview.setState(-1);
            result = orderMapper.updateStateByPrimaryKey(id,10);
        }else{
            orderReview.setState(1);
            result = orderMapper.updateStateByPrimaryKey(id,30);
        }
        if (result < 1) {
            throw new XmallException("审核失败,请重新尝试");
        }
        int reviewResult = orderReviewMapper.insertSelective(orderReview);
        if (reviewResult < 1) {
            throw new XmallException("审核失败,请重新尝试");
        }
        return 0;
    }

    @Override
    public void downloadExcel(int[] state,String minDate, String maxDate, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        List<OrderExcelDto> reulst = orderMapper.selectDownloadList(state,minDate,maxDate);
        HashMap<Integer,String> stateMap = new HashMap<>();
        stateMap.put(0,"待确认");
        stateMap.put(10,"待取药");
        stateMap.put(20,"待审核");
        stateMap.put(30,"待配送");
        stateMap.put(35,"配送中");
        stateMap.put(40,"已完成");
        int i = 1;
        for (OrderExcelDto dto:reulst){
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("序号",i);
            map.put("下单时间",dto.getCreateTime());
            map.put("订单确认时间",dto.getComfireTime());
            map.put("配药完成时间",dto.getPeiyaoTime());
            map.put("审核完成时间",dto.getReviewTime());
            map.put("配送员接单时间",dto.getDeliveryTime());
            map.put("配送完成时间",dto.getFinishTime());
            map.put("收货人姓名",dto.getReceiverName());
            List<MedicineItemDto> medicineItemDtos = orderItemMapper.selectMedicinListByOrder(dto.getOrderId());
            if (medicineItemDtos.size()>0){
                map.put("配送药品",medicineItemDtos.get(0).getMedicineName());
                map.put("数量",medicineItemDtos.get(0).getNum());
                map.put("金额",medicineItemDtos.get(0).getNum()*medicineItemDtos.get(0).getPrice());
            }
            map.put("配送地址",dto.getReceiverAddress());
            map.put("是否有录音",StringUtils.isBlank(dto.getRadioPath())? "否":"是");
            map.put("配送人",dto.getDeliveryName());
                map.put("下单人",dto.getMemberName());
            map.put("下单人属性","");
            map.put("订单状态",stateMap.get(dto.getStatus()));
            list.add(map);
            i++;
        }
        FileUtil.downloadExcel(list, response);

    }

    @Override
    @Transactional
    public void updateOrderPrintState(String[] ids,int state) {
        log.info("改变订单打印状态");
        for (String id:ids){
            TbOrder order = orderMapper.selectPrintStateById(id);
            if (order!=null){
                int printState = order.getIsPrint();
                if (printState == state){
                    return;
                }
                if (printState!=0){
                    if (orderMapper.updatePrintStateById(id,3)<1){
                        throw  new XmallException("更新订单打印状态失败");
                    }
                }else {
                    if (orderMapper.updatePrintStateById(id,state)<1){
                        throw  new XmallException("更新订单打印状态失败");
                    }
                }
            }
        }
    }


    private OrderDto order2dto(TbOrder order) {
        OrderDto dto = new OrderDto();
        dto.setState(order.getStatus());
        dto.setReserveTime(order.getReserveTime());
        dto.setOrderId(order.getOrderId());
        dto.setPaymentType(order.getPaymentType());
        dto.setInsuranceType(order.getInsuranceType());
        dto.setInsurance(order.getInsurance());

        return dto;
    }
}
